package zelix.hack.hacks;

import java.lang.reflect.Field;

import net.minecraft.client.Minecraft;
import zelix.hack.Hack;
import zelix.hack.HackCategory;
import zelix.utils.TimerUtils;
import zelix.utils.system.Connection;
import zelix.value.Mode;
import zelix.value.ModeValue;
import zelix.utils.Wrapper;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.play.server.SPacketEntityVelocity;
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
import zelix.value.NumberValue;

public class Velocity extends Hack {

	public ModeValue mode;
	private boolean ishurt;
	private TimerUtils velocitytimer = new TimerUtils();
	// public NumberValue percentage;

	private float velocityTick = 0;

	public static Boolean velocityInput = false;

	Minecraft mc = Wrapper.INSTANCE.mc();
	NumberValue velocityTickValue;


	public Velocity() {
		super("Velocity", HackCategory.COMBAT);

		this.mode = new ModeValue("Mode", new Mode("AAC", false), new Mode("Simple", true), new Mode("AAC4", false) , new Mode("Tick" , false));
		this.velocityTickValue = new NumberValue("Tick", 10D, 0D, 10D);
		this.addValue(mode , velocityTickValue);
	}

	@Override
	public String getDescription() {
		return "Prevents you from getting pushed by players, mobs and flowing water.";
	}

	@Override
	public void onClientTick(ClientTickEvent event) {
		if(mode.getMode("AAC").isToggled()) {
			EntityPlayerSP player = Wrapper.INSTANCE.player();
			if(player.hurtTime > 0 && player.hurtTime <= 6) {
				player.motionX *= 0.5;
				player.motionZ *= 0.5;
				player.motionY *=0.96;
		      }
		      if(player.hurtTime > 0 && player.hurtTime < 6) {
		    	  player.motionX = 0.0;
		    			  player.motionZ = 0.0;
		      }
		}else if(mode.getMode("AAC4").isToggled()) {
			if(Wrapper.INSTANCE.player().isInWater()||Wrapper.INSTANCE.player().isInLava()) {
				return;
			}
			
			if (!Wrapper.INSTANCE.player().onGround) {
		        if (ishurt) {
		        	Field field = ReflectionHelper.findField(EntityPlayer.class,
							new String[] { "speedInAir", "field_71102_ce" });
					try {

						if (!field.isAccessible()) {
							field.setAccessible(true);
						}

						field.setFloat(Wrapper.INSTANCE.player(), 0.02f);

					} catch (Exception e) {
						//////////System.out.println(e);
					}
		           // Wrapper.INSTANCE.player().speedInAir = 0.02f
		            Wrapper.INSTANCE.player().motionX *= 0.6;
		            Wrapper.INSTANCE.player().motionZ *= 0.6;
		        }
		    } else if (velocitytimer.hasReached(80L)) {
		        ishurt = false;
		    	Field field = ReflectionHelper.findField(EntityPlayer.class,
						new String[] { "speedInAir", "field_71102_ce" });
				try {

					if (!field.isAccessible()) {
						field.setAccessible(true);
					}

					field.setFloat(Wrapper.INSTANCE.player(), 0.02f);

				} catch (Exception e) {
					//////////System.out.println(e);
				}
		    }
		}else if (mode.getMode("Tick").isToggled()){
			if(velocityTick > velocityTickValue.getValue().floatValue()) {
				if(mc.player.motionY > 0) mc.player.motionY = 0.0;
				mc.player.motionX = 0.0;
				mc.player.motionZ = 0.0;
				mc.player.jumpMovementFactor = -0.00001f;
				velocityInput = false;
			}
			if(mc.player.onGround && velocityTick > 1) {
				velocityInput = false;
			}
		}
		super.onClientTick(event);
	}

	@Override
	public boolean onPacket(Object packet, Connection.Side side) {
		if (packet instanceof SPacketEntityVelocity && mode.getMode("Simple").isToggled()
				&& Wrapper.INSTANCE.player().hurtTime >= 0) {
			SPacketEntityVelocity p = (SPacketEntityVelocity) packet;
			if (p.getEntityID() == Wrapper.INSTANCE.player().getEntityId()) {
				return false;
			}
		} else if (packet instanceof SPacketEntityVelocity && mode.getMode("AAC4").isToggled()&& Wrapper.INSTANCE.player().hurtTime >= 0) {
			SPacketEntityVelocity p = (SPacketEntityVelocity) packet;
			if (p.getEntityID() == Wrapper.INSTANCE.player().getEntityId()) {
				ishurt = true;
				velocitytimer.reset();
			}
		}
		return true;
	}
}
